import type { OGImage, PageMetadata, TitleMetadata } from '@onlook/models';
import { Button } from '@onlook/ui/button';
import { Icons } from '@onlook/ui/icons';
import { Input } from '@onlook/ui/input';
import { Separator } from '@onlook/ui/separator';
import { Textarea } from '@onlook/ui/textarea';
import { useRef } from 'react';
import type { FaviconRef } from './favicon';
import { Favicon } from './favicon';
import type { ImagePickerRef } from './image';
import ImagePicker from './image';

const getImageUrl = (images: OGImage | OGImage[] | undefined): string | undefined => {
    if (!images) {
        return undefined;
    }
    const image = Array.isArray(images) ? images[0] : images;
    if (typeof image === 'string') {
        return image;
    }
    if (image instanceof URL) {
        return image.toString();
    }
    return image?.url?.toString();
};

interface MetadataFormProps {
    title: string;
    titleObject: TitleMetadata;
    description: string;
    isDirty: boolean;
    projectUrl?: string;
    isSimpleTitle: boolean;
    disabled?: boolean;
    isSaving?: boolean;
    onTitleChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
    onTitleTemplateChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
    onTitleAbsoluteChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
    onDescriptionChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
    onImageSelect: (file: File) => void;
    onFaviconSelect?: (file: File) => void;
    onDiscard: () => void;
    onSave: () => void;
    showFavicon?: boolean;
    currentMetadata?: PageMetadata;
    defaultTitle?: string;
    defaultDescription?: string;
    isRoot?: boolean;
}

const DEFAULT_TITLE = 'My New App';
const DEFAULT_DESCRIPTION = 'Generated by Onlook';

export const MetadataForm = ({
    title,
    titleObject,
    description,
    isDirty,
    projectUrl,
    isSimpleTitle,
    disabled = false,
    isSaving = false,
    onTitleChange,
    onTitleTemplateChange,
    onTitleAbsoluteChange,
    onDescriptionChange,
    onImageSelect,
    onFaviconSelect,
    onDiscard,
    onSave,
    showFavicon = false,
    currentMetadata,
    isRoot,
}: MetadataFormProps) => {
    const imagePickerRef = useRef<ImagePickerRef>(null);
    const faviconRef = useRef<FaviconRef>(null);

    const handleDiscard = () => {
        imagePickerRef.current?.reset();
        faviconRef.current?.reset();
        onDiscard();
    };

    const renderTitle = () => {
        if (isSimpleTitle) {
            return (
                <div className="grid grid-cols-2 text-foreground-onlook">
                    <div className="flex items-center">
                        <h2 className="text-regular font-medium">Title</h2>
                    </div>
                    <Input
                        placeholder="Title"
                        value={title}
                        className="col-span-1 text-miniPlus break-words transition-all duration-150 ease-in-out backdrop-blur-lg bg-background-secondary/75 text-foreground-primary border-background-secondary/75"
                        onChange={onTitleChange}
                        disabled={disabled}
                    />
                </div>
            );
        } else {
            return (
                <div className="flex flex-col gap-4">
                    <h2 className="text-title3 text-foreground-onlook">Title Settings</h2>

                    <div className="grid grid-cols-2 text-foreground-onlook">
                        <div className="flex items-center">
                            <h3 className="text-regular font-medium">Default Title</h3>
                        </div>
                        <Input
                            placeholder="Default title"
                            value={titleObject.default || ''}
                            className="col-span-1 text-miniPlus break-words transition-all duration-150 ease-in-out backdrop-blur-lg bg-background-secondary/75 text-foreground-primary border-background-secondary/75"
                            onChange={onTitleChange}
                            disabled={disabled}
                        />
                    </div>
                    {!isRoot ? (
                        <div className="grid grid-cols-2 text-foreground-onlook">
                            <div className="flex flex-col max-w-52">
                                <h3 className="text-regular font-medium">Absolute Title</h3>
                                <p className="text-small">
                                    Ignores template from parents layout when set.
                                </p>
                            </div>
                            <Input
                                placeholder="Absolute title"
                                value={titleObject.absolute || ''}
                                className="col-span-1 text-miniPlus break-words transition-all duration-150 ease-in-out backdrop-blur-lg bg-background-secondary/75 text-foreground-primary border-background-secondary/75"
                                onChange={onTitleAbsoluteChange}
                                disabled={disabled}
                            />
                        </div>
                    ) : (
                        <div className="grid grid-cols-2 text-foreground-onlook">
                            <div className="flex flex-col max-w-52">
                                <h3 className="text-regular font-medium">Title Template</h3>
                                <p className="text-small">
                                    Use %s as placeholder for child page titles (e.g., "%s | My
                                    Site")
                                </p>
                            </div>
                            <Input
                                placeholder="%s | My Site"
                                value={titleObject.template || ''}
                                className="col-span-1 text-miniPlus break-words transition-all duration-150 ease-in-out backdrop-blur-lg bg-background-secondary/75 text-foreground-primary border-background-secondary/75"
                                onChange={onTitleTemplateChange}
                                disabled={disabled}
                            />
                        </div>
                    )}
                </div>
            );
        }
    };

    return (
        <div className="text-sm flex flex-col h-full">
            <div className="flex flex-col gap-6 p-6 pb-24 overflow-y-auto flex-1">
                {renderTitle()}

                <Separator />

                <div className="grid grid-cols-2 h-44">
                    <div className="flex flex-col text-foreground-onlook col-span-1 max-w-52">
                        <h2 className="text-regular font-medium">Page Description</h2>
                        <p className="text-small">
                            This is the information that will show up on search engines below your
                            page title.
                        </p>
                    </div>

                    <Textarea
                        placeholder={DEFAULT_DESCRIPTION}
                        value={description}
                        className="col-span-1 text-miniPlus break-words transition-all duration-150 ease-in-out backdrop-blur-lg bg-background-secondary/75 text-foreground-primary border-background-secondary/75"
                        onChange={onDescriptionChange}
                        disabled={disabled}
                        style={{
                            resize: 'none',
                            height: 'auto',
                            overflowY: 'auto',
                            overflowX: 'hidden',
                            overscrollBehavior: 'contain',
                            lineHeight: '1.5',
                        }}
                    />
                </div>

                <div className="flex flex-col gap-2">
                    <h2 className="text-regular text-foreground-onlook">Search Engine Preview</h2>
                    <div className="bg-background/50 p-4 rounded-md border gap-1.5 flex flex-col">
                        <p className="text-miniPlus text-blue-500">{projectUrl}</p>
                        <h3 className="text-regular">{title || DEFAULT_TITLE}</h3>
                        <p className="text-sm text-muted-foreground line-clamp-2">
                            {description || DEFAULT_DESCRIPTION}
                        </p>
                    </div>
                </div>
                <Separator />
                {/* TODO: Implement */}
                <div className="flex flex-col gap-4">
                    <h2 className="text-title3">Imagery</h2>
                    <div className="grid grid-cols-2 text-foreground-onlook">
                        <div className="flex flex-col max-w-52">
                            <p className="text-regular font-medium">Social Preview</p>
                            <p className="text-small">Cropped to 1200 × 630 pixels</p>
                        </div>
                        <div>
                            <ImagePicker
                                ref={imagePickerRef}
                                onImageSelect={onImageSelect}
                                url={getImageUrl(currentMetadata?.openGraph?.images)}
                            />
                        </div>
                    </div>
                    {showFavicon && (
                        <div className="grid grid-cols-2">
                            <div className="text-gray-200 max-w-52">
                                <p className="text-regular font-medium">Favicon</p>
                                <p className="text-small">
                                    This is the small icon that shows up in search engines and in
                                    your browser. It should be 64 × 64 pixels.
                                </p>
                            </div>
                            <Favicon
                                ref={faviconRef}
                                onImageSelect={onFaviconSelect!}
                                url={currentMetadata?.icons?.icon?.toString()}
                            />
                        </div>
                    )}
                </div>
            </div>
            
            {/* Pinned buttons at the bottom */}
            <div className="sticky bottom-0 bg-background border-t border-border/50 p-6" style={{ borderTopWidth: '0.5px' }}>
                <div className="flex justify-end gap-4">
                    <Button
                        variant="outline"
                        className="flex items-center gap-2 px-4 py-2 bg-background border border-border/50"
                        type="button"
                        onClick={handleDiscard}
                        disabled={!isDirty || disabled}
                    >
                        <span>Discard changes</span>
                    </Button>
                    <Button
                        variant="secondary"
                        className="flex items-center gap-2 px-4 py-2"
                        type="button"
                        onClick={onSave}
                        disabled={!isDirty || disabled || isSaving}
                    >
                        {isSaving && <Icons.LoadingSpinner className="h-4 w-4 animate-spin" />}
                        <span>{isSaving ? 'Saving...' : 'Save changes'}</span>
                    </Button>
                </div>
            </div>
        </div>
    );
};
